---
title: ChangeNotifierProvider
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
import CodeBlock from "@theme/CodeBlock";
import todos from "!!raw-loader!/docs/providers/change_notifier_provider/todos.dart";
import todosConsumer from "!!raw-loader!/docs/providers/change_notifier_provider/todos_consumer.dart";
import { trimSnippet, Foo } from "../../../../../src/components/CodeSnippet";

`ChangeNotifierProvider` (来自 flutter_riverpod/hooks_riverpod) 
是一个用于监听和暴露Flutter本身的 [ChangeNotifier] 的provider。

Riverpod不鼓励使用 `ChangeNotifierProvider` ，它的存在主要是为了：

- an easy transition from `package:provider` when using its `ChangeNotifierProvider`
- 当使用它的 `ChangeNotifierProvider` 时，简单地从 `package:provider` 迁移。
- 支持可变状态，即使不可变的状态更好。

:::info
更倾向于使用 [StateNotifierProvider]。
只有在绝对需要可变状态时才考虑使用 `ChangeNotifierProvider`。
:::

使用可变状态而不是不可变状态有时会更高效。
但缺点是它可能更难维护，并可能破坏各种功能。  
比如说如果状态是可变的，
用于优化widget重新构建的 `provider.select` 可能不起作用，
因为Select会认为值没有改变。  
因此，使用不可变的数据结构有时会更快。
制定特定用例的基准测试非常重要，以确保通过使用 `ChangeNotifierProvider` 时能真正获得性能。

下面是用法示例，我们可以使用 `ChangeNotifierProvider` 来实现待办清单。
这样做将允许我们公开 `addTodo` 等方法，让UI修改用户交互中的待办清单：

<CodeBlock>{trimSnippet(todos)}</CodeBlock>

现在我们已经定义了一个 `ChangeNotifierProvider`，
我们可以用它来与UI中的待办清单交互：

<CodeBlock>{trimSnippet(todosConsumer)}</CodeBlock>

[state_notifier]: https://pub.dev/packages/state_notifier
[statenotifierprovider]: ./state_notifier_provider
[changenotifier]: https://api.flutter.dev/flutter/foundation/ChangeNotifier-class.html
[provider]: ./provider
[futureprovider]: ./future_provider
